<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
<script>
// 'use strict';

// Object静态方法（构造函数的方法/类的方法）
// function Object(n){
//     this.name = n;
// }
// Object.defineProperty = function (){}// 静态方法
// Object.defineProperty();

// Object.defineProperty(obj,property,descriptor)定义对象的属性和属性描述符
// obj 要定义属性的对象
// property 要定义的属性名
// descriptor 属性描述符（属性描述对象）

var obj1 = {
    name: '晶哥哥',
    age: 18,
    sex: '男'
}

// 定义对象属性
Object.defineProperty(obj1,'sex',{// 属性描述对象
    configurable: true,// 是否可配置（会影响sex是否可删除、是否可重新修改配置）
    enumerable: true,// 是否可枚举
    writable: true,// 是否可写
    value: '妖'// sex属性的值
});

// delete obj1.sex;// 删除sex属性
// console.log( obj1 );

// for (var key in obj1){
//     console.log( key );// 'name' 'age' 'sex' -> 可枚举属性
// }

// obj1.sex = '女';
// console.log( obj1.sex );// '女'

// console.log( obj1.sex );// '妖'


var obj2 = {
    name: '静哥哥',
    age: 19,
    sex: '男'
}

// 定义对象属性
obj2._sex = obj2.sex;// 先保存sex的初始值
Object.defineProperty(obj2,'sex',{// 属性描述对象
    configurable: true,
    enumerable: true,

    // writable: true,
    // value: '女',

    // writable和value 不能与 setter和getter 同时存在！！！

    // 属性访问器：setter getter
    // 访问sex时，getter自动被调用
    // 修改sex时，setter自动被调用
    get(){// getter返回sex属性的值
        console.log( 'getter被调用。。。1' );
        // return obj2.sex;// 会导致get无限循环调用

        // 返回中间属性的值
        return obj2._sex;
    },
    set(newValue){// setter设置sex属性的值
        console.log( 'setter被调用。。。2',newValue );
        // obj2.sex = newValue;// 会导致set无限循环调用

        // 通过中间属性来修改sex属性的值
        obj2._sex = newValue;
    }
});

console.log( obj2 );// 
obj2.sex = '女';// 修改sex的值，会触发setter
console.log( obj2.sex );// 访问sex属性，会触发getter

</script>
</body>
</html>